package model;

import static org.junit.Assert.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.junit.Test;

import exceptions.AuctionLimitReachedException;
import exceptions.BadDateException;
import exceptions.BadTimeException;
import exceptions.SameNpoInYearException;

//Spring 2012 TCSS360 Deliverable 3
//Otis Alexander

public class CalendarTest {
	
	private static final int ONE_DAY_IN_MILLI = 0x5265C00;

	private static final long THREE_MONTHS_IN_MILLI = 0x1CF7C5800L;
	
	CalendarModel cm = new CalendarModel();
	
	@Test(expected=BadTimeException.class)
	public void testTwoHourTimeLimitBetweenAuctionsSameTime() throws BadDateException, BadTimeException, SameNpoInYearException,
	AuctionLimitReachedException{
		
		cm.addAuction(null, "a", null, convertDate("June 24, 2012"), 12, 15, 0, null);
		
		cm.addAuction(null, "b", null, convertDate("June 24, 2012"), 12, 15, 0, null);	
	}
	
	@Test(expected=BadTimeException.class)
	public void testTwoHourTimeLimitBetweenAuctionsHourBefore() throws BadDateException, BadTimeException, SameNpoInYearException,
	AuctionLimitReachedException{
		
		cm.addAuction(null, "a", null, convertDate("June 24, 2012"), 12, 15, 0, null);
		
		cm.addAuction(null, "b", null, convertDate("June 24, 2012"), 9, 11, 0, null);
	}
	
	@Test(expected=BadTimeException.class)
	public void testTwoHourTimeLimitBetweenAuctionsHourAfter() throws BadDateException, BadTimeException, SameNpoInYearException,
	AuctionLimitReachedException{
		
		cm.addAuction(null, "a", null, convertDate("June 24, 2012"), 12, 15, 0, null);
		
		cm.addAuction(null, "b", null, convertDate("June 24, 2012"), 16, 18, 0, null);
	}
	
	@Test
	public void testTwoHourTimeLimitBetweenAuctionsTwoHoursBetween() throws BadDateException, BadTimeException, SameNpoInYearException,
	AuctionLimitReachedException{
		
		cm.addAuction(null, "a", null, convertDate("June 24, 2012"), 12, 15, 0, null);
		
		cm.addAuction(null, "b", null, convertDate("June 24, 2012"), 17, 19, 0, null);
		
		assertEquals(12, cm.getAuctions(convertDate("June 24, 2012")).get(0).getStartTime(), 0);
		assertEquals(17, cm.getAuctions(convertDate("June 24, 2012")).get(1).getStartTime(), 0);
	}
	
	@Test(expected=AuctionLimitReachedException.class)
	public void testFiveAuctionLimitInSevenDays() throws BadDateException, BadTimeException, SameNpoInYearException,
	AuctionLimitReachedException{
		
		cm.addAuction(null, "a", null, convertDate("June 23, 2012"), 12, 15, 0, null);
		
		cm.addAuction(null, "b", null, convertDate("June 24, 2012"), 8, 10, 0, null);
		
		cm.addAuction(null, "c", null, convertDate("June 26, 2012"), 12, 15, 0, null);
		
		cm.addAuction(null, "d", null, convertDate("June 27, 2012"), 9, 11, 0, null);
		
		cm.addAuction(null, "e", null, convertDate("June 28, 2012"), 12, 15, 0, null);
		
		//Sixth auction will cause error;
		
		cm.addAuction(null, "f", null, convertDate("June 25, 2012"), 9, 11, 0, null);
	}
	
	@Test(expected=SameNpoInYearException.class)
	public void testTwoSameNpoAuctionsScheduledInFuture() throws BadDateException, BadTimeException, SameNpoInYearException,
	AuctionLimitReachedException{
		
		cm.addAuction(null, "a", null, convertDate("June 24, 2012"), 12, 15, 0, null);
		
		cm.addAuction(null, "a", null, convertDate("June 24, 2012"), 8, 10, 0, null);
	}
	
	@Test(expected=BadDateException.class)
	public void testScheduledAuction31DaysInFuture() throws BadDateException, BadTimeException, SameNpoInYearException,
	AuctionLimitReachedException{
		
		Date d = new Date();
		d.setTime(System.currentTimeMillis() + THREE_MONTHS_IN_MILLI + ONE_DAY_IN_MILLI);
		cm.addAuction(null, "a", null, d, 12, 15, 0, null);
	}
	
	@Test(expected=AuctionLimitReachedException.class)
	public void test26ScheduledAuctionsInFuture() throws BadDateException, BadTimeException, SameNpoInYearException,
	AuctionLimitReachedException{
		
		Date d = new Date();
		d.setTime(System.currentTimeMillis());
		for (int i = 0; i < 27; i++){
		d.setTime(d.getTime() + ONE_DAY_IN_MILLI);
		cm.addAuction(null, Integer.toString(i), null, d, 12, 15, 0, null);
		}
	}	
	
	private Date convertDate(String the_birthday) {
		SimpleDateFormat format = new SimpleDateFormat("MMMMM dd, yyyy");
		Date d = null;
		
		try {
			d = format.parse(the_birthday);
		} catch (ParseException e) {
			System.out.println("Bad date format");
		}

		return d;
	}
}
